package com.ijava.base.service.impl;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;

import com.ijava.base.dao.OrganizationDAO;
import com.ijava.base.domain.Organization;
import com.ijava.base.domain.Organization;
import com.ijava.base.domain.User;
import com.ijava.base.service.OrganizationService;

public class OrganizationServiceImpl implements OrganizationService {
	private static final Logger logger = LoggerFactory.getLogger(OrganizationServiceImpl.class);
	private OrganizationDAO dao;
	private DataSource dataSource;

	public OrganizationDAO getDao() {
		return dao;
	}

	public void setDao(OrganizationDAO dao) {
		this.dao = dao;
	}

	public void remove(String id) throws Exception {
		dao.remove(id);
	}

	public void removeProcess(Organization organization) throws Exception {
		try {
			String pid = get(organization.getOrgId()).getOrgParentId();
			remove(organization.getOrgId());
			Organization parent = get(pid);
			if (null != parent) {
				List list = find(parent);
				if (list.size() == 0) {
					parent.setOrgIsLeaf(1);
					update(parent);
				}
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public void mutilRemove(Organization organization) throws Exception {
		try {
			String[] keys = organization.getKeys();
			if(null == keys)
				return;
			for (int i = 0; i < keys.length; i++) {
				remove(keys[i]);
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public void save(Organization organization) throws Exception {
		dao.save(organization);
	}

	public String persist(Organization organization) throws Exception {
		try {
			JdbcTemplate template = new JdbcTemplate(getDataSource());
			List params = new ArrayList();
			params.add(organization.getOrgId());
			params.add(organization.getOrgParentId());
			params.add(organization.getOrgCode());
			params.add(organization.getOrgName());
			params.add(organization.getOrgIsLeaf());
			params.add(organization.getOrgLevel());
			params.add(organization.getCrUserId());
			params.add(organization.getCrTime());
			params.add(organization.getRowEnable());
			params.add(organization.getRowOrder());
			StringBuffer sqlBuffer = new StringBuffer(64);
			sqlBuffer.append("INSERT INTO ORGANIZATION (");
			sqlBuffer.append("ORG_ID,ORG_PARENT_ID,ORG_CODE,ORG_NAME,ORG_IS_LEAF,");
			sqlBuffer.append("ORG_LEVEL,CR_USER_ID,CR_TIME,ROW_ENABLE,ROW_ORDER");
			sqlBuffer.append(") VALUES(?,?,?,?,?,?,?,?,?,?)");
			template.update(sqlBuffer.toString(), params.toArray());
		} catch (Exception e) {
			logger.error("", e);
			organization.setOrgId(null);
			throw e;
		}
		return organization.getOrgId();
	}

	public void saveAll(Organization organization, User user) throws Exception {
		try {

			List organizations = new ArrayList();
			String[] orgIds = organization.getOrgIds();
			String[] orgCodes = organization.getOrgCodes();
			String[] orgNames = organization.getOrgNames();
			String[] orgExplains = organization.getOrgExplains();
			int[] orgIsLeafs = organization.getOrgIsLeafs();
			int[] rowOrders = organization.getRowOrders();
			for (int i = 0; i < orgIds.length; i++) {
				Organization e = new Organization();
				if ("_".equals(orgIds[i])) {
					e.setOrgId(null);
					e.setCrTime(new Date(System.currentTimeMillis()));
					e.setCrUserId(user.getUserId());
					e.setOrgIsLeaf(1);
				} else {
					e.setOrgId(orgIds[i]);
					e.setOrgIsLeaf(orgIsLeafs[i]);
					e.setUpTime(new Date(System.currentTimeMillis()));
					e.setUpUserId(user.getUserId());
				}
				e.setOrgLevel(organization.getOrgLevel() + 1);
				e.setOrgParentId(organization.getOrgId());
				e.setRowEnable(1);
				e.setOrgCode(orgCodes[i]);
				e.setOrgName(orgNames[i]);
				e.setOrgExplain(orgExplains[i]);
				e.setRowOrder(rowOrders[i]);

				organizations.add(e);
			}

			for (int i = 0; i < organizations.size(); i++) {
				Organization org = (Organization) organizations.get(i);
				dao.saveOrUpdate(org);
			}

			organization = dao.get(organization.getOrgId());
			if (null != organization) {
				organization.setOrgIsLeaf(0);
				dao.update(organization);
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public void update(Organization organization) throws Exception {
		dao.update(organization);
	}

	public void merge(Organization organization) throws Exception {
		dao.merge(organization);
	}

	public void saveOrUpdate(Organization organization) throws Exception {
		dao.saveOrUpdate(organization);
	}

	public Organization get(String id) throws Exception {
		return dao.get(id);
	}

	public List find(Organization organization) throws Exception {
		try {
			List paramList = new ArrayList();
			StringBuffer condition = new StringBuffer();

			condition.append(" where orgParentId = ?");
			paramList.add(organization.getOrgId());

			String queryString = "from " + Organization.class.getName()
					+ condition.toString();
			return dao.find(queryString, paramList);
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public List findWithPaging(Organization organization) throws Exception {
		try {
			int firstRow = (organization.getPageNo() - 1)
					* organization.getPageSize();
			int maxRow = organization.getPageSize();

			// JdbcTemplate template = new JdbcTemplate(dataSource);
			// int total =
			// template.queryForInt("SELECT COUNT(1) FROM TABLE_NAME");
			// organization.setTotal(total);

			List paramList = new ArrayList();
			StringBuffer condition = new StringBuffer();
			if (StringUtils.hasLength(organization.getOrgId())) {
				condition.append(" where orgParentId = ?");
				paramList.add(organization.getOrgId());

				List list = dao.find("select count(*) from "
						+ Organization.class.getName() + condition.toString(),
						paramList);
				organization.setTotal(Integer.parseInt(list.get(0).toString()));

				String queryString = "from " + Organization.class.getName()
						+ condition.toString();
				return dao.findWithPaging(queryString, paramList, firstRow,
						maxRow);
			} else {
				return new ArrayList();
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public List findTree(String orgId, List list) throws Exception {
		try {
			List paramList = new ArrayList();
			paramList.add(orgId);

			List childList = dao.find("from " + Organization.class.getName()
					+ " where orgParentId = ?", paramList);
			for (int i = 0; i < childList.size(); i++) {
				Organization e = (Organization) childList.get(i);
				list.add(e);
				if (e.getOrgIsLeaf() == 0) {
					findTree(e.getOrgId(), list);
				}
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
		return list;
	}

	public List findChild(Organization organization) throws Exception {
		try {
			List paramList = new ArrayList();
			String[] keys = organization.getKeys();
			
			String sql = "from " + Organization.class.getName()
					+ " where orgParentId = ?";
			if (null != keys && keys.length > 0) {
				StringBuffer condition = new StringBuffer("from "
						+ Organization.class.getName()
						+ " where orgParentId in (");
				for (int i = 0; i < keys.length; i++) {
					paramList.add(keys[i]);
					condition.append("?");
					if (i != (keys.length - 1)) {
						condition.append(",");
					}
				}
				condition.append(")");
				sql = condition.toString();
			} else {
				paramList.add(organization.getOrgId());
			}
			return dao.find(sql, paramList);
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

}
